
use crate::run_plan::{RunPlanExpr};
use crate::conf_init::{MapResult, MapErr};
use crate::logical_plan::expr::window::LogicalPlanExprWindow;

pub mod work_node;
pub mod work_space;
pub mod expr;

/*
conf->LogicalPlanExpr->RunPlan->PhysicalPlanTrait->PhysicalPlan

LogicalPlanExpr就是客户具体的表达式集合，大致分几类：
    1）filter判断类型
    2）简单hand处理类型
    3）复杂处理类型
physicalPlanTrait是physicalplan的抽象化，由具体的PhysicalPlan来执行具体动作
RunPlan 对PhysicalPlan的组合方式，决定了数据在不同PhysicalPlan之间的跳转方式

pub fn logicalplan_map_to_runplan(expr: &LogicalPlanExpr, pre_define: &HashMap<String, LogicalPlanExpr>)
        -> MapResult<Box<RunPlan>>{

    match expr{
        /*
        LogicalPlanExpr::Binary(left,op,right) => {
            let left = match logicalplan_try_map_physicalplan_expr(left){
                MapResult::Ok(left) => {
                    RunPlanPhysicalPlanFuncArg::Normal(left)
                },
                MapResult::Err(_) => {
                    let t = logicalplan_map_to_runplan(left, pre_define)?;
                    RunPlanPhysicalPlanFuncArg::OtherRunPlan(t)
                }
            };
            let right = match logicalplan_try_map_physicalplan_expr(right){
                MapResult::Ok(right) => {
                    RunPlanPhysicalPlanFuncArg::Normal(right)
                },
                MapResult::Err(_) => {
                    let t = logicalplan_map_to_runplan(right, pre_define)?;
                    RunPlanPhysicalPlanFuncArg::OtherRunPlan(t)
                }
            };

            let op_func = logicalplan_try_map_physicalplan(op.to_func_name())?;
            return MapResult::Ok(
                Box::new(RunPlan::Binary(Box::new(left),op_func,Box::new(right)))
            );
        },
        */
        LogicalPlanExpr::ConfValue(_) => {
            return MapResult::Err(
                MapErr::new(
                    format!("LogicalPlan [{:?}] cannot map to RunPlan", expr)
                )
            );
        },
        LogicalPlanExpr::RealValue(_) => {
            return MapResult::Err(
                MapErr::new(
                    format!("LogicalPlan [{:?}] cannot map to RunPlan", expr)
                )
            );
        },
        LogicalPlanExpr::ElementValue(_) => {
            return MapResult::Err(
                MapErr::new(
                    format!("LogicalPlan [{:?}] cannot map to RunPlan", expr)
                )
            );
        },
        LogicalPlanExpr::Func(name, args) => {
            let mut func_args = Vec::new();

            for arg in args.iter(){
                match logical_plan_expr_try_map_physical_plan_expr(arg){
                    Ok(arg) => {
                        func_args.push(RunPlanPhysicalPlanFuncArg::Normal(arg));
                    },
                    Err(_) => {
                        let arg = logicalplan_map_to_runplan(arg, pre_define)?;
                        func_args.push(RunPlanPhysicalPlanFuncArg::OtherRunPlan(arg));
                    },
                }
            }
            let func = logicalplan_try_map_physicalplan(name)?;
            return MapResult::Ok(Box::new(RunPlan::Func(func, func_args)));
        },
        LogicalPlanExpr::OutSideExpr(outside_expr) => {
            if let Some(outside_expr) = pre_define.get(outside_expr.as_str()){
                return logicalplan_map_to_runplan(&outside_expr, pre_define);
            }else{
                return MapResult::Err(MapErr::new(format!("outside [{}] not exist", outside_expr)));
            }
        },
        LogicalPlanExpr::Window(window_expr) => {
            return MapResult::Err(MapErr::new(format!("LogicalPlanExpr::Window not support")));
        },
    }
}
*/

fn logical_plan_window_map_to_run_plan(_window_expr: &LogicalPlanExprWindow)
    -> MapResult<Box<RunPlanExpr>>{


    return MapResult::Err(MapErr::new(format!(" ")));
}
